package org.common.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.common.mapper.RoleMenuMapper;
import org.common.model.entity.Menu;
import org.common.mapper.MenuMapper;
import org.common.model.entity.Role;
import org.common.model.entity.RoleMenu;
import org.common.model.enums.MenuStatusEnum;
import org.common.model.enums.MenuTypeEnum;
import org.common.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2024-04-21
 */
@Service
@RequiredArgsConstructor
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {

    private final RoleMenuMapper roleMenuMapper;

    /**
     * 将菜单数据封装成树形数据格式返回
     */
    @Override
    public List<Tree<String>> queryMenuList() {
        List<Menu> menusList = baseMapper.selectList(null);
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        // 最大递归深度
        treeNodeConfig.setDeep(3);
        List<Tree<String>> treeNodes = TreeUtil.build(menusList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    //这俩属性必须设置
                    tree.setId(treeNode.getId().toString());
                    tree.setParentId(treeNode.getParentId().toString());
                    // 扩展属性 ...
                    tree.putExtra("label", treeNode.getTitle());
                    tree.putExtra("button", treeNode.getButton());
                });
        return treeNodes;
    }

    @Override
    public List<Integer> queryRoleMenuList(Role role) {
        //如果是admin管理员角色则返回所有的菜单及按钮
        if(role.getRoleName().equalsIgnoreCase("管理员")){
            //由于前端展示需求，只需返回按钮级别的id即可
            //过滤出按钮的id并且状态是开启的
            List<Menu> menuList = baseMapper.selectList(null);
            List<Integer> buttonIds = menuList.stream().filter(menu -> (menu.getType() == MenuTypeEnum.BUTTON.getCode()) && (menu.getStatus() == MenuStatusEnum.OPEN.getCode()))
                    .collect(Collectors.toList())
                    .stream().map(Menu::getId).collect(Collectors.toList());
            return buttonIds;
        }else{
            QueryWrapper<RoleMenu> wrapper = new QueryWrapper<>();
            wrapper.eq("role_id", role.getId());
            List<Integer> menuIdList = roleMenuMapper.selectList(wrapper).stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(menuIdList)){
                //TODO：其实这里不应该直接返回数据，还需从menu表中查询菜单或按钮是否是开启状态，否则不返回。
                //由于前端展示需求，只需返回按钮级别的id即可
                //过滤出按钮的id并且状态是开启的
                List<Menu> menuList = baseMapper.selectBatchIds(menuIdList);
                List<Integer> buttonIds = menuList.stream().filter(menu -> (menu.getType() == MenuTypeEnum.BUTTON.getCode()) && (menu.getStatus() == MenuStatusEnum.OPEN.getCode()))
                        .collect(Collectors.toList())
                        .stream().map(Menu::getId).collect(Collectors.toList());
                return buttonIds;
            }
            return null;
        }
    }

    /**
     * 将菜单数据封装成树形数据格式返回
     * @param menuIds
     */
//    private List<Tree<String>> buildTree(List<Integer> menuIds) {
//        List<Menu> menusList = menuMapper.selectBatchIds(menuIds);
//        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
//        // 最大递归深度
//        treeNodeConfig.setDeep(2);
//        List<Tree<String>> treeNodes = TreeUtil.build(menusList, "0", treeNodeConfig,
//                (treeNode, tree) -> {
//                    //这俩属性必须设置
//                    tree.setId(treeNode.getId().toString());
//                    tree.setParentId(treeNode.getParentId().toString());
//                    // 扩展属性 ...
//                    tree.putExtra("path", treeNode.getPath());
//                    tree.putExtra("name", treeNode.getName());
//                    tree.putExtra("title", treeNode.getTitle());
//                    tree.putExtra("hidden", treeNode.getHidden());
//                    tree.putExtra("icon", treeNode.getIcon());
//                });
//        return treeNodes;
//    }
}
